import 'dart:core';

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

import '../common/flatPanel.dart';
import '../models/topicItem.dart';
import '../parts/topicItemDialog.dart';
import '../utils/dataSource.dart';
import '../utils/screw.dart';

mixin TopicItemController {
  final mDb = DataSource();

  String mTable;
  int placeHolder = -1;
  var mViewState = ViewState.Initial;
  var mTopic = '';
  var mTopics = <String>[];
  var mItems = <TopicItem>[];
  TopicItem mItem;

  void onConnectDB();

  void onUpdateTopics();

  void onUpdateView();

  void onAddItem();

  void onEditItem();

  void onDeleteItem();

  void onTapItem();

  Future<void> disposeAction() async {
    mTopics.clear();
    mItems.clear();
    await mDb.close();
  }

  Future<void> connectDbAction(
      BuildContext context, String entry, Function function) async {
    bool result = await mDb.connectFromHive(entry);
    if (result) {
      function();
    } else {
      Screw.showToast(context, '无法连接到数据库!');
    }
  }

  Future<void> addItemAction(BuildContext context) async {
    var inputItem = TopicItem();
    if (mTopic.isNotEmpty)
      inputItem.topic = mTopic;
    else
      inputItem.topic = 'Default';

    var item = await showTopicItemDialog(context, item: inputItem);
    if (item == null) return;

    if (mDb.isConnect) {
      var result = await mDb.query(
          'insert into $mTable (topic,label,detail,addition) values (?,?,?,?)',
          [item.topic, item.label, item.detail, item.addition]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> editItemAction(BuildContext context) async {
    if (mItem?.id == 0) return;

    var item = await showTopicItemDialog(context, item: mItem);
    if (item == null || mItem.isEqual(item)) return;

    if (mDb.isConnect) {
      var result = await mDb.query(
          'update $mTable set topic=?,label=?,detail=?,addition=? where id=?',
          [item.topic, item.label, item.detail, item.addition, item.id]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> deleteItemAction() async {
    if (mItem?.id == 0) return;

    if (mDb.isConnect) {
      var result =
          await mDb.query('delete from $mTable where id=?', [mItem.id]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> updateTopicsAction() async {
    if (mTopics.isNotEmpty) mTopics.clear();

    if (mDb.isConnect) {
      var items = <String>[];
      var results = await mDb.query('select topic from $mTable group by topic');
      results.forEach((element) {
        items.add(element[0]);
      });
      mTopics = items;
    }
  }

  Future<void> updateViewAction() async {
    if (mTopic.isEmpty) return;

    if (mDb.isConnect) {
      var items = <TopicItem>[];
      var results = await mDb.query(
          'select id,label,detail,addition from $mTable where topic=?',
          [mTopic]);
      results.forEach((element) {
        var item = TopicItem(
            id: element[0],
            topic: mTopic,
            label: element[1] ?? '',
            detail: element[2] ?? '',
            addition: element[3] ?? '');
        items.add(item);
      });
      mItems = items;
    }
  }

  Widget genFloatingActionButtonAction() {
    switch (mViewState) {
      case ViewState.Initial:
        return FloatingActionButton(
          child: FaIcon(FontAwesomeIcons.plug),
          onPressed: onConnectDB,
        );
      case ViewState.CheckedView:
        return FloatingActionButton(
          child: Icon(Icons.edit),
          onPressed: onEditItem,
        );
      default:
        return FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: onAddItem,
        );
    }
  }

  Widget genTopicViewAction({TextStyle style}) {
    return ListView.builder(
        itemCount: mTopics.length,
        itemBuilder: (c, index) {
          return ListTile(
              leading: Icon(Icons.arrow_forward_ios),
              title: Text(mTopics[index], style: style),
              onTap: () {
                mTopic = mTopics[index];
                onUpdateView();
              });
        });
  }

  Widget genGridViewAction({TextStyle style}) {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        //子组件宽高长度比例
        childAspectRatio: 8.0,
      ),
      itemCount: mItems.length,
      itemBuilder: (c, index) {
        return ListTile(
          leading: Icon(placeHolder == mItems[index].id
              ? Icons.radio_button_checked
              : Icons.radio_button_unchecked),
          title: Text(mItems[index].label, style: style),
          subtitle: Text(mItems[index].detail),
          onTap: () {
            mItem = mItems[index];
            onTapItem();
          },
        );
      },
    );
  }

  Widget genListViewAction({TextStyle style}) {
    return ListView.separated(
      itemCount: mItems.length,
      itemBuilder: (context, index) {
        return ListTile(
          leading: Icon(placeHolder == mItems[index].id
              ? Icons.radio_button_checked
              : Icons.radio_button_unchecked),
          title: Text(mItems[index].label, style: style),
          subtitle: Text(mItems[index].detail),
          onTap: () {
            mItem = mItems[index];
            onTapItem();
          },
        );
      },
      separatorBuilder: (context, i) => Divider(),
    );
  }

  Future<void> _showDeleteConfirmDialog(BuildContext context) async {
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('操作确认'),
            content: Text('确定要删除吗？ 不可恢复！'),
            actions: <Widget>[
              FlatButton(
                child: Text('取消'),
                onPressed: () => Navigator.of(context).pop(),
              ),
              FlatButton(
                child: Text('确定'),
                onPressed: () {
                  onDeleteItem();
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
        });
  }

  PopupMenuButton<String> genPopupMenuButtonAction(BuildContext context) {
    return PopupMenuButton<String>(
      offset: Offset(0, 60),
      itemBuilder: (context) {
        return <PopupMenuEntry<String>>[
          PopupMenuItem<String>(
            value: 'updateTopics',
            child: Text('更新列表'),
          ),
          PopupMenuItem<String>(
            value: 'updateView',
            child: Text('更新视图'),
          ),
          PopupMenuDivider(),
          PopupMenuItem<String>(
            value: 'deleteItem',
            child: Text('删除...'),
          ),
        ];
      },
      onSelected: (value) {
        if (value == 'updateTopics')
          onUpdateTopics();
        else if (value == 'updateView')
          onUpdateView();
        else if (value == 'deleteItem') _showDeleteConfirmDialog(context);
      },
    );
  }

  Widget genScaffoldAction(BuildContext context, String title,
      {TextStyle topicViewStyle, TextStyle listViewStyle}) {
    return Scaffold(
      appBar: AppBar(title: Text(title), actions: <Widget>[
        genPopupMenuButtonAction(context),
      ]),
      body: FlatPanel(
        child: Row(
          children: <Widget>[
            Expanded(
              flex: 1,
              child: genTopicViewAction(style: topicViewStyle),
            ),
            Expanded(
              flex: 3,
              child: genListViewAction(style: listViewStyle),
            ),
          ],
        ),
      ),
      floatingActionButton: genFloatingActionButtonAction(),
    );
  }
}
